return check_vdi_ref
+def valid_vtpm(func):
+ """Decorator to verify if vtpm_ref is valid before calling
+ method.
+
+ @param func: function with params: (self, session, vtpm_ref)
+ @rtype: callable object
+ """
+ def check_vtpm_ref(self, session, vtpm_ref, *args, **kwargs):
+ xendom = XendDomain.instance()
+ if type(vtpm_ref) == type(str()) and \
+ xendom.is_valid_dev('vtpm', vtpm_ref):
+ return func(self, session, vtpm_ref, *args, **kwargs)
+ else:
+ return {'Status': 'Failure',
+ 'ErrorDescription': XEND_ERROR_VTPM_INVALID}
+
+ # make sure we keep the 'api' attribute
+ if hasattr(func, 'api'):
+ check_vtpm_ref.api = func.api
+
+ return check_vtpm_ref
+
def valid_sr(func):
"""Decorator to verify if sr_ref is valid before calling
method.
'VBD': (valid_vbd, session_required),
'VIF': (valid_vif, session_required),
'VDI': (valid_vdi, session_required),
+ 'VTPM':(valid_vtpm, session_required),
'SR': (valid_sr, session_required)}
# Cheat methods
'actions_after_reboot',
'actions_after_suspend',
'actions_after_crash',
- 'TPM_instance',
- 'TPM_backend',
'bios_boot',
'platform_std_VGA',
'platform_serial',
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vtpms())
- def vm_get_tpm_instance(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo() # unsupported by xc
-
- def vm_get_tpm_backend(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo() # unsupported by xc
-
def vm_get_pci_bus(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
return xen_api_error(XEND_ERROR_VDI_INVALID)
+ # Xen API: Class VTPM
+ # ----------------------------------------------------------------
+
+ VTPM_attr_ro = [ ]
+ VTPM_attr_rw = ['type',
+ 'VM',
+ 'backend',
+ 'instance']
+
+ VTPM_attr_inst = VTPM_attr_rw
+
+ # object methods
+ def vtpm_get_record(self, session, vtpm_ref):
+ xendom = XendDomain.instance()
+ vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
+ if not vm:
+ return xen_api_error(XEND_ERROR_VTPM_INVALID)
+ cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
+ if not cfg:
+ return xen_api_error(XEND_ERROR_VTPM_INVALID)
+ valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
+ self.Base_attr_ro + self.Base_attr_rw
+ for k in cfg.keys():
+ if k not in valid_vtpm_keys:
+ del cfg[k]
+
+ return xen_api_success(cfg)
+
+ # class methods
+ def vtpm_create(self, session, vtpm_struct):
+ xendom = XendDomain.instance()
+ if xendom.is_valid_vm(vtpm_struct['VM']):
+ dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
+ try:
+ vtpm_ref = dom.create_vtpm(vtpm_struct)
+ xendom.managed_config_save(dom)
+ return xen_api_success(vtpm_ref)
+ except XendError:
+ return xen_api_error(XEND_ERROR_TODO)
+ else:
+ return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
+
+
# Xen API: Class SR
# ----------------------------------------------------------------
SR_attr_ro = ['VDIs',
'vcpus_features_force_on',
'vcpus_features_force_off',
'actions_after_suspend',
- 'tpm_instance',
- 'tpm_backends',
'bios_boot',
'platform_std_vga',
'platform_serial',
# ------------------
cfg['vif_refs'] = []
cfg['vbd_refs'] = []
+ cfg['vtpm_refs'] = []
for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
if dev_type == 'vif':
cfg['vif_refs'].append(dev_uuid)
elif dev_type in ('vbd','tap'):
cfg['vbd_refs'].append(dev_uuid)
+ elif dev_type == 'vtpm':
+ cfg['vtpm_refs'].append(dev_uuid)
return cfg
cfg['vif_refs'] = []
if 'vbd_refs' not in cfg:
cfg['vbd_refs'] = []
+ if 'vtpm_refs' not in cfg:
+ cfg['vtpm_refs'] = []
return cfg
self['vif_refs'] = []
if 'vbd_refs' not in self:
self['vbd_refs'] = []
+ if 'vtpm_refs' not in self:
+ self['vtpm_refs'] = []
def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
if dev_type not in XendDevices.valid_devices():
self['device'][dev_uuid] = (dev_type, dev_info)
self['vbd_refs'].append(dev_uuid)
return dev_uuid
-
+
+ elif dev_type == 'vtpm':
+ if cfg_xenapi.get('type'):
+ dev_info['type'] = cfg_xenapi.get('type')
+ dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_info['uuid'] = dev_uuid
+ self['device'][dev_uuid] = (dev_type, dev_info)
+ self['vtpm_refs'].append(dev_uuid)
+ return dev_uuid
+
elif dev_type == 'tap':
dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
return dev_uuid
+ def create_vtpm(self, xenapi_vtpm):
+ """Create a VTPM device from the passed struct in Xen API format.
+
+ @return: uuid of the device
+ @rtype: string
+ """
+
+ dev_uuid = self.info.device_add('vtpm', cfg_xenapi = xenapi_vtpm)
+ if not dev_uuid:
+ raise XendError('Failed to create device')
+
+ if self.state in (DOM_STATE_HALTED,):
+ sxpr = self.info.device_sxpr(dev_uuid)
+ devid = self.getDeviceController('vtpm').createDevice(sxpr)
+ raise XendError("Device creation failed")
+
+ return dev_uuid
+
def has_device(self, dev_class, dev_uuid):
return (dev_uuid in self.info['%s_refs' % dev_class])
XEND_ERROR_VM_INVALID = ('EVMINVALID', 'VM Invalid')
XEND_ERROR_VBD_INVALID = ('EVBDINVALID', 'VBD Invalid')
XEND_ERROR_VIF_INVALID = ('EVIFINVALID', 'VIF Invalid')
+XEND_ERROR_VTPM_INVALID = ('EVTPMINVALID', 'VTPM Invalid')
XEND_ERROR_VDI_INVALID = ('EVDIINVALID', 'VDI Invalid')
XEND_ERROR_SR_INVALID = ('ESRINVALID', 'SR Invalid')
XEND_ERROR_TODO = ('ETODO', 'Lazy Programmer Error')
if inst == -1:
inst = int(sxp.child_value(config, 'instance' , '0'))
+ typ = sxp.child_value(config, 'type')
+ uuid = sxp.child_value(config, 'uuid')
+
log.info("The domain has a TPM with pref. instance %d and devid %d.",
inst, devid)
back = { 'pref_instance' : "%i" % inst,
'resume' : "%s" % (self.vm.getResume()) }
+ if typ:
+ back['type'] = typ
+ if uuid:
+ back['uuid'] = uuid
+
front = { 'handle' : "%i" % devid }
return (devid, back, front)
- def configuration(self, devid):
-
- result = DevController.configuration(self, devid)
+ def getDeviceConfiguration(self, devid):
+ """Returns the configuration of a device"""
+ result = DevController.getDeviceConfiguration(self, devid)
- instance = self.readBackend(devid, 'instance')
+ (instance, uuid, type) = \
+ self.readBackend(devid, 'instance',
+ 'uuid',
+ 'type')
if instance:
- result.append(['instance', instance])
+ result['instance'] = instance
+ if uuid:
+ result['uuid'] = uuid
+ if type:
+ result['type'] == type
return result
This option may be repeated to add more than one vif.
Specifying vifs will increase the number of interfaces as needed.""")
-gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
+gopts.var('vtpm', val="instance=INSTANCE,backend=DOM,type=TYPE",
fn=append_value, default=[],
use="""Add a TPM interface. On the backend side use the given
instance as virtual TPM instance. The given number is merely the
which instance number will actually be assigned to the domain.
The associtation between virtual machine and the TPM instance
number can be found in /etc/xen/vtpm.db. Use the backend in the
- given domain.""")
+ given domain.
+ The type parameter can be used to select a specific driver type
+ that the VM can use. To prevent a fully virtualized domain (HVM)
+ from being able to access an emulated device model, you may specify
+ 'paravirtualized' here.""")
gopts.var('access_control', val="policy=POLICY,label=LABEL",
fn=append_value, default=[],
"""Create the config for virtual TPM interfaces.
"""
vtpm = vals.vtpm
- vtpm_n = 1
- for idx in range(0, vtpm_n):
- if idx < len(vtpm):
- d = vtpm[idx]
- instance = d.get('instance')
- if instance == "VTPMD":
- instance = "0"
- else:
- if instance != None:
- try:
- if int(instance) == 0:
- err('VM config error: vTPM instance must not be 0.')
- except ValueError:
- err('Vm config error: could not parse instance number.')
- backend = d.get('backend')
- config_vtpm = ['vtpm']
- if instance:
- config_vtpm.append(['pref_instance', instance])
- if backend:
- config_vtpm.append(['backend', backend])
- config_devs.append(['device', config_vtpm])
+ if len(vtpm) > 0:
+ d = vtpm[0]
+ instance = d.get('instance')
+ if instance == "VTPMD":
+ instance = "0"
+ else:
+ if instance != None:
+ try:
+ if int(instance) == 0:
+ err('VM config error: vTPM instance must not be 0.')
+ except ValueError:
+ err('Vm config error: could not parse instance number.')
+ backend = d.get('backend')
+ typ = d.get('type')
+ config_vtpm = ['vtpm']
+ if instance:
+ config_vtpm.append(['pref_instance', instance])
+ if backend:
+ config_vtpm.append(['backend', backend])
+ if typ:
+ config_vtpm.append(['type', type])
+ config_devs.append(['device', config_vtpm])
def configure_vifs(config_devs, vals):